/**
 * @author: 全局工具函数
 * @author: YoungYa
 * @date: 2024-10-16 10:50:33
 */
import { Request } from 'express';
import * as fs from 'fs';

import { International } from '@/models/international.model'; // 数据库实体
import { REQUEST_CODE, REQUEST_MSG } from '@/utils/enums';
import type { Response } from '@/utils/types';

/**
 * @description: 统一返回体
 * @author: YoungYa
 */
export const responseMessage = <T = any>(
  data,
  msg: string = REQUEST_MSG.SUCCESS,
  code: number = REQUEST_CODE.SUCCESS,
): Response<T> => {
  return { data, msg, code };
};

/**
 * @description: 将数组转成树形数据
 * @param {any} resource: 源数据
 * @param {string} id
 * @param {string} parentId
 * @param {string} children
 * @author: YoungYa
 */
export function initializeTree<T>(
  resource: T[],
  id: string,
  parentId: string,
  children: string,
): T[] {
  const temp = JSON.parse(JSON.stringify(resource));
  // 以id为键，当前对象为值，存入一个新的对象中
  const tempObj = {};
  for (const i in temp) {
    tempObj[temp[i][id]] = temp[i];
  }
  return temp.filter((father: T) => {
    // 把当前节点的所有子节点找到
    const childArr = temp.filter((child: T) => father[id] == child[parentId]);
    childArr.length > 0 ? (father[children] = childArr) : '';
    // 只返回第一级数据；如果当前节点的fatherId不为空，但是在父节点不存在，也为一级数据
    return father[parentId] === null || !tempObj[father[parentId]];
  });
}

/**
 * @description: 将树形数据转成层级对象，主要是国际化数据
 * @param {LangModel} resource
 * @param {string} lang
 * @param {string} name
 * @author: YoungYa
 */
export const initializeLang = (
  resource: International[],
  lang: string,
  name = 'name',
): Record<string, any> => {
  const result = {};
  // 遍历数组
  for (let i = 0; i < resource.length; i++) {
    const resourceItem = resource[i];

    // 递归函数
    function recursive(obj: International, serilKey = '') {
      // 拼接对象名
      let pKey = serilKey;
      pKey += pKey ? `.${obj[name]}` : obj[name];
      // 当前层级是否有数据，给 result 赋值
      if (obj[lang]) {
        result[pKey] = obj[lang];
      }
      // 判断是否有子级，有就递归遍历
      if (obj.children?.length && Array.isArray(obj.children)) {
        for (let j = 0; j < obj.children.length; j++) {
          const child = obj.children[j];
          recursive(child, pKey);
        }
      }
    }

    // 循环执行
    recursive(resourceItem);
  }
  return result;
};

/**
 * @description: 生成文件上传文件夹
 * @param {string} filePath
 * @author: YoungYa
 */
export const checkDirAndCreate = (filePath: string): void => {
  const pathArr = filePath.split('/');
  let checkPath = '.';
  let item: string;
  for (item of pathArr) {
    checkPath += `/${item}`;
    if (!fs.existsSync(checkPath)) {
      fs.mkdirSync(checkPath);
    }
  }
};

/**
 * @description: 获取客户端真实 IP
 * @param {Request} req
 */
export const getRealIp = (req: Request): string => {
  const result =
    req.headers['x-forwarded-for'] ||
    req.headers['x-real-ip'] ||
    req.socket.remoteAddress ||
    req.ip;
  return Array.isArray(result) ? result[0] : result;
};

/**
 * @description: 获取文件后缀
 * @param {string} fileName
 */
export const getFilePrefix = (fileName: string): string => fileName.split('.').pop();

/**
 * @description: 获取文件名, 不带后缀
 * @param fileName
 */
export const getFileName = (fileName: string): string => fileName.replace(/\.[^/.]+$/, '');

/**
 * @description: 根据文件名获取对应的 MIME 类型
 * @param filename
 */
export const getContentType = (filename: string): string => {
  const extension = filename.split('.').pop()?.toLowerCase() || '';

  const mimeTypes: { [key: string]: string } = {
    // 图片类型
    jpg: 'image/jpeg',
    jpeg: 'image/jpeg',
    png: 'image/png',
    gif: 'image/gif',
    webp: 'image/webp',
    svg: 'image/svg+xml',
    bmp: 'image/bmp',
    tiff: 'image/tiff',
    ico: 'image/x-icon',

    // 文档类型
    pdf: 'application/pdf',
    doc: 'application/msword',
    docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    xls: 'application/vnd.ms-excel',
    xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    ppt: 'application/vnd.ms-powerpoint',
    pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    txt: 'text/plain',
    csv: 'text/csv',
    json: 'application/json',
    xml: 'application/xml',
    html: 'text/html',
    htm: 'text/html',
    js: 'application/javascript',
    ts: 'application/typescript',

    // 音频类型
    mp3: 'audio/mpeg',
    wav: 'audio/wav',
    ogg: 'audio/ogg',
    aac: 'audio/aac',
    flac: 'audio/flac',

    // 视频类型
    mp4: 'video/mp4',
    webm: 'video/webm',
    avi: 'video/x-msvideo',
    mkv: 'video/x-matroska',
    mov: 'video/quicktime',
    wmv: 'video/x-ms-wmv',

    // 压缩文件类型
    zip: 'application/zip',
    rar: 'application/x-rar-compressed',
    '7z': 'application/x-7z-compressed',
    tar: 'application/x-tar',
    gz: 'application/gzip',
    bz2: 'application/x-bzip2',

    // 其他类型
    exe: 'application/octet-stream',
    dmg: 'application/octet-stream',
    iso: 'application/octet-stream',
  };

  // 返回对应的 MIME 类型，如果未找到则返回默认的二进制流类型
  return mimeTypes[extension] || 'application/octet-stream';
};
